package ninja.awesome.game.main;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import ninja.awesome.framework.Graphics;
import ninja.awesome.framework.impl.AndroidGame;
import ninja.awesome.game.Assets;
import ninja.awesome.game.MainGameScreen;
import ninja.awesome.game.NinjaGame;
import ninja.awesome.game.classes.Friendly;
import ninja.awesome.game.classes.Hostile;
import ninja.awesome.game.classes.Neutral;
import ninja.awesome.game.gameobject.Building;
import ninja.awesome.game.gameobject.Bush;
import ninja.awesome.game.gameobject.Enemy;
import ninja.awesome.game.gameobject.Enemy1;
import ninja.awesome.game.gameobject.Road;
import ninja.awesome.game.gameobject.Tree;
import ninja.awesome.game.gameobject.Weather;

public class Controller {
	private LinkedList<Weather> il = new LinkedList<Weather>();
	private LinkedList<Building> bl = new LinkedList<Building>();
	private LinkedList<Friendly> fl = new LinkedList<Friendly>();
	private LinkedList<Hostile> hl = new LinkedList<Hostile>();
	private LinkedList<Hostile> enemyList = new LinkedList<Hostile>();
	private LinkedList<Hostile> bossList = new LinkedList<Hostile>();
	private LinkedList<Neutral> nl = new LinkedList<Neutral>();
	private LinkedList<Road> rl = new LinkedList<Road>();
	private LinkedList<Bush> bushL1 = new LinkedList<Bush>(); // bush cover the

	// road
	private LinkedList<Tree> treeL1 = new LinkedList<Tree>(); // tree for house
	// bush covering road
	private LinkedList<Bush> bushL2 = new LinkedList<Bush>(); // bush cover the
																// house
	// bush covering house

	private LinkedList<Tree> treeL2 = new LinkedList<Tree>(); // tree for road
	private static final HashMap EnemyBuilder = new HashMap();

	// Variables
	Friendly f;
	Hostile h;
	Neutral n;
	Random r = new Random();
	Weather TempIsland;
	Building b; // defined from Jung Hwan Kim's Implementation
	Road rd;
	Bush bush1, bush2;
	Tree tree1, tree2;
	MainGameScreen game;
	Sprites s;

	public Controller(MainGameScreen mainGame, Sprites s) {
		this.game = mainGame;
		this.s = s;
		for (int x = 1; x <= 3; x++) {
		}
	}

	public void update() {
		// FRIENDLY
		for (int i = 0; i < il.size(); i++) {
			TempIsland = il.get(i);
			TempIsland.update();
		}
		for (int i = 0; i < fl.size(); i++) {
			f = fl.get(i);

			// REMOVE BULLET OUT OF BOUNDS
			if (f.getY() < 0) {
				removeFriendly(f);
			}
			f.update();
		}
		// Update BOSS LIST
		for (int i = 0; i < bossList.size(); i++) {
			bossList.get(i).update();
		}
		// Update Enemy List
		for (int i = 0; i < enemyList.size(); i++) {
			enemyList.get(i).update();
		}

		// HOSTILE
		for (int i = 0; i < hl.size(); i++) {
			h = hl.get(i);
			h.update();
		}

		// Neutral
		for (int i = 0; i < nl.size(); i++) {
			n = nl.get(i);
			n.update();
		}
		// Building from Jung Hwan Kim's Implementation
		for (int i = 0; i < bl.size(); i++) {
			b = bl.get(i);
			b.update();
		}

		// bush
		for (int i = 0; i < bushL1.size(); i++) {
			bush1 = bushL1.get(i);
			bush1.update();
		}
		for (int i = 0; i < bushL2.size(); i++) {
			bush2 = bushL2.get(i);
			bush2.update();
		}
		// tree
		for (int i = 0; i < treeL1.size(); i++) {
			tree1 = treeL1.get(i);
			tree1.update();
		}
		for (int i = 0; i < treeL2.size(); i++) {
			tree2 = treeL2.get(i);
			tree2.update();
		}
		List<Road> rmList = new ArrayList<Road>();
		List<Road> aList = new ArrayList<Road>();
		// road
		for (Road r : rl) {
			r.update();
		}
		for (int i = 0; i < rl.size(); ++i) {
			Road r = rl.get(i);
			if (r.xLoc < -1000) {
				rmList.add(r);
				Road addedRoad = new Road(2000, AndroidGame.ROAD_Y, this.game, this, s);
				aList.add(addedRoad);
				addedRoad.update();
			} else if (r.xLoc > 2000) {
				rmList.add(r);
				Road addedRoad = new Road(-1000, AndroidGame.ROAD_Y, this.game, this, s);
				aList.add(addedRoad);
				addedRoad.update();
			}
		}
		rl.removeAll(rmList);
		rl.addAll(aList);
	}

	public void draw(Graphics g) {

		// Road from Jung Hwan Kim's Implementation
		for (int i = 0; i < rl.size(); i++) {
			rd = rl.get(i);
			rd.draw(g);
		}
		for (int i = 0; i < treeL1.size(); i++) {
			tree2 = treeL2.get(i);
			tree2.draw(g);
		}
		// bush for building
		for (int i = 0; i < bushL2.size(); i++) {
			bush2 = bushL2.get(i);
			bush2.draw(g);
		}
		// Building from Jung Hwan Kim's
		for (int i = 0; i < bl.size(); i++) {
			b = bl.get(i);
			b.draw(g);
		}

		for (Hostile boss : bossList) {
			boss.draw(g);
		}

		for (Hostile enemy : enemyList) {
			enemy.draw(g);
		}

		// Neutral
		for (int i = 0; i < nl.size(); i++) {
			n = nl.get(i);
			n.draw(g);
		}

		// FRIENDLY
		for (int i = 0; i < il.size(); i++) {
			TempIsland = il.get(i);
			TempIsland.draw(g);
		}
		for (int i = 0; i < fl.size(); i++) {
			f = fl.get(i);
			f.draw(g);
		}

	}

	public void draw1(Graphics g) {
		// HOSTILE
		for (int i = 0; i < hl.size(); i++) {
			h = hl.get(i);
			h.draw(g);
		}

		// HOSTILE
		for (int i = 0; i < hl.size(); i++) {
			h = hl.get(i);
			h.draw(g);
		}
		// tree
		for (int i = 0; i < treeL1.size(); i++) {
			tree1 = treeL1.get(i);
			tree1.draw(g);
		}
		// bush
		for (int i = 0; i < bushL1.size(); i++) {
			bush1 = bushL1.get(i);
			bush1.draw(g);
		}
	}

	public void addFriendly(Friendly block) {
		fl.add(block);
		Assets.slash.play(1f);
	}

	public void removeFriendly(Friendly block) {
		fl.remove(block);
	}

	public void addHostile(Hostile h) {
		this.hl.add(h);
	}

	public void removeHostile(Hostile h) {
		this.hl.remove(h);
	}

	public void addIsland(Weather i) {
		this.il.add(i);
	}

	// add building from Jung Hwan Kim's Implementation
	public void addBuilding(Building b) {
		this.bl.add(b);
	}

	// remove building from Jung Hwan Kim's Implementation
	public void removeBuilding(Building b) {
		this.bl.remove(b);
	}

	public void addRoad(Road rd) {
		this.rl.add(rd);
	}

	public void removeRoad(Road rd) {
		this.rl.remove(rd);
	}

	public void addBush1(Bush bh) { // add bush within road
		this.bushL1.add(bh);

	}

	public void removeBush(Bush bh) {// remove bush within road
		this.bushL1.remove(bh);

	}

	public void addBush2(Bush bh) { // add bush within house
		this.bushL2.add(bh);
	}

	public void removeBush2(Bush bh) {// remove bush within house
		this.bushL2.remove(bh);

	}

	public void removeTree1(Tree tree) {
		this.treeL1.remove(tree);
	}

	public void addTree1(Tree tree) {
		this.treeL1.add(tree);
	}

	public void removeTree2(Tree tree) {
		this.treeL2.remove(tree);
	}

	public void addTree2(Tree tree) {
		this.treeL2.add(tree);
	}

	public void spawnRandomEnemy(int enemyCount) {
		spawnRandomEnemy(enemyCount, 0);
	}

	public void spawnRandomEnemy(int enemyCount, int additionalHealth) {
		for (int i = 0; i < enemyCount; ++i) {
			int type = r.nextInt(2); // 0 is back, 1 is front
			Enemy newEnemy = null;
			Enemy1 newEnemy1 = null;
			if (type == 0) {
				if (r.nextInt(2) == 0) {
					newEnemy = new Enemy(-100, getRandomYForEnemy(), 1, this, this.game, s);
				} else {
					newEnemy1 = new Enemy1(-100, getRandomYForEnemy(), 1, this, this.game, s);
				}

			} else {
				if (r.nextInt(2) == 0) {
					newEnemy = new Enemy(NinjaGame.WIDTH + 100, getRandomYForEnemy(), 1, this, this.game, s);
				} else {
					newEnemy1 = new Enemy1(NinjaGame.WIDTH + 100, getRandomYForEnemy(), 1, this, this.game, s);
				}

			}
			if (newEnemy != null) {
				int health = newEnemy.getHealth();
				newEnemy.setHealth(health + additionalHealth);
				newEnemy.setMaxHealth(health + additionalHealth);
				enemyList.add(newEnemy);
			} else if (newEnemy1 != null) {
				int health = newEnemy1.getHealth();
				newEnemy1.setHealth(health + additionalHealth);
				newEnemy1.setMaxHealth(health + additionalHealth);
				enemyList.add(newEnemy1);
			}

		}
	}

	private int getRandomYForEnemy() {
		return AndroidGame.ROAD_Y + r.nextInt(AndroidGame.ROAD_HEIGHT) - 20;
	}

	// spawn buildings from Jung Hwan Kim's Implementation
	public void spawnBuilding(int direction) {
		if (direction == 0) { // initial
			// addBuilding(new Building (-1*800, -100, this.game,this,s)); //
			// spawn left building at initial game
			addBuilding(new Building(0 * 500, 20, this.game, this, s)); // spawn
																		// middle
																		// building
																		// at
																		// initial
																		// game
			// addBuilding(new Building(1*800, -100, this.game,this,s)); //
			// spawn right building at initial game
		} else
			addBuilding(new Building(direction * NinjaGame.WIDTH + 300, 20, this.game, this, s));
	}

	public void spawnTree(int direction) {

		if (direction == 0) {

			addTree1(new Tree(0 * 500, 330, this.game, this, s));// road

			addTree2(new Tree(0 * 500, 190, this.game, this, s)); // house

		} else {
			addTree1(new Tree(direction * NinjaGame.WIDTH, 330, this.game, this, s));// road

			addTree2(new Tree(direction * NinjaGame.WIDTH + 400, 190, this.game, this, s));//
			// house

			// when player moves right
			// the building spawn right
			// if left
			// building spawn left
		}
	}

	public void spawnRoad(int direction) {

		if (direction == 0) {
			addRoad(new Road(-1 * 1000, AndroidGame.ROAD_Y, this.game, this, s));
			addRoad(new Road(0 * 1000, AndroidGame.ROAD_Y, this.game, this, s));
			addRoad(new Road(1 * 1000, AndroidGame.ROAD_Y, this.game, this, s));
		} else {
			addRoad(new Road(direction * 1000, AndroidGame.ROAD_Y, this.game, this, s));
		}
	}

	public void spawnBush(int direction) {

		if (direction == 0) {

			addBush1(new Bush(0 * 500, 540, this.game, this, s));// road
			addBush2(new Bush(0 * 500, 347, this.game, this, s)); // house

		} else {
			addBush1(new Bush(direction * 1908, 540, this.game, this, s));// road
			addBush2(new Bush(direction * 1908, 347, this.game, this, s));// house

			// when player moves right
			// the building spawn right
			// if left
			// building spawn left
		}
	}

	public void addNeutral(Neutral n) {
		this.nl.add(n);
	}

	public void removeNeutral(Neutral n) {
		this.nl.remove(n);
	}

	public LinkedList<Friendly> getFriendly() {
		return fl;
	}

	public LinkedList<Hostile> getHostile() {
		return hl;
	}

	public LinkedList<Neutral> getNeutral() {
		return nl;
	}

	// return LinkedList Building from Jung Hwan Kim's Implemetation
	public LinkedList<Building> getBuilding() {
		return bl;
	}

	public LinkedList<Road> getRoad() {
		return rl;
	}

	public LinkedList<Bush> getBush1() {
		return bushL1;
	}

	public LinkedList<Bush> getBush2() {
		return bushL2;
	}

	public LinkedList<Tree> getTree1() {
		return treeL1;
	}

	public LinkedList<Tree> getTree2() {
		return treeL2;
	}

	public LinkedList<Hostile> getBossList() {
		return bossList;
	}

	public void setBossList(LinkedList<Hostile> bossList) {
		this.bossList = bossList;
	}

	public LinkedList<Hostile> getEnemyList() {
		return enemyList;
	}

	public void setEnemyList(LinkedList<Hostile> enemyList) {
		this.enemyList = enemyList;
	}

}
